{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 卷积神经网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "卷积层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([20, 33, 26, 100])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conv = torch.nn.Conv2d(16, 33, kernel_size=(3, 5), \n",
    "        stride=(2, 1), padding=(4, 2), dilation=(3, 1))\n",
    "inputs = torch.randn(20, 16, 50, 100)\n",
    "outputs = conv(inputs)\n",
    "outputs.size()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "池化层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([20, 16, 50])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pool = nn.MaxPool1d(kernel_size=2, stride=2)\n",
    "inputs = torch.randn(20, 16, 100)\n",
    "outputs = pool(inputs)\n",
    "outputs.size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[0., 2., 0., 4.]]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.tensor([[[1, 2, 3, 4, 5]]], dtype=torch.float)\n",
    "pool = nn.MaxPool1d(kernel_size=2, stride=2, return_indices=True)\n",
    "outputs, indices = pool(inputs)\n",
    "unpool = nn.MaxUnpool1d(kernel_size=2, stride=2)\n",
    "recovers = unpool(outputs, indices)\n",
    "recovers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[0., 2., 0., 4., 0.]]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.tensor([[[1, 2, 3, 4, 5]]], dtype=torch.float)\n",
    "pool = nn.MaxPool1d(kernel_size=2, stride=2, return_indices=True)\n",
    "outputs, indices = pool(inputs)\n",
    "unpool = nn.MaxUnpool1d(kernel_size=2, stride=2)\n",
    "recovers = unpool(outputs, indices, output_size=inputs.size())\n",
    "recovers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[0., 2., 0., 4., 0., 6., 0., 8.]]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pool = nn.MaxPool1d(2, stride=2, return_indices=True)\n",
    "unpool = nn.MaxUnpool1d(2, stride=2)\n",
    "inputs = torch.tensor([[[1, 2, 3, 4, 5, 6, 7, 8]]], dtype=torch.float)\n",
    "outputs, indices = pool(inputs)\n",
    "unpool(outputs, indices)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上采样层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\torch\\nn\\functional.py:2539: UserWarning: Default upsampling behavior when mode=linear is changed to align_corners=False since 0.4.0. Please specify align_corners=True if the old behavior is desired. See the documentation of nn.Upsample for details.\n",
      "  \"See the documentation of nn.Upsample for details.\".format(mode))\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(tensor([[[1., 0., 2.]]]),\n",
       " tensor([[[1.0000, 1.0000, 0.6667, 0.3333, 0.0000, 0.6667, 1.3333, 2.0000,\n",
       "           2.0000]]]))"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.tensor([[[1, 0, 2]]], dtype=torch.float)\n",
    "# m = nn.Upsample(scale_factor=3, mode='nearest')\n",
    "m = nn.Upsample(scale_factor=3, mode='linear')\n",
    "inputs, m(inputs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[[1., 0., 2.]]]),\n",
       " tensor([[[1.0000, 0.9375, 0.5625, 0.1875, 0.3750, 1.1250, 1.8750, 2.0000]]]),\n",
       " tensor([[[ 7.0000,  6.5625,  3.9375,  1.3125,  2.6250,  7.8750, 13.1250,\n",
       "           14.0000]]]))"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.tensor([[[1, 0, 2]]], dtype=torch.float)\n",
    "# m = nn.Upsample(size=9, mode='nearest')\n",
    "m = nn.Upsample(size=8, mode='linear')\n",
    "inputs, m(inputs), m(inputs) * 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[[1., 0., 2.]]]),\n",
       " tensor([[[1.0000, 0.7500, 0.2500, 0.5000, 1.5000, 2.0000]]]))"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.arange(0, 4).reshape(1, 1, 4)\n",
    "inputs = torch.tensor([[[1, 0, 2]]], dtype=torch.float)\n",
    "# m = nn.Upsample(scale_factor=2, mode='nearest')\n",
    "m = nn.Upsample(scale_factor=2, mode='linear')\n",
    "inputs, m(inputs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[[1., 1., 2., 2.],\n",
       "          [1., 1., 2., 2.],\n",
       "          [3., 3., 4., 4.],\n",
       "          [3., 3., 4., 4.]]]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.arange(1, 5, dtype=torch.float).view(1, 1, 2, 2)\n",
    "upsample = nn.Upsample(scale_factor=2, mode='nearest')\n",
    "upsample(inputs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "补全层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[[[ 0.,  1.,  2.,  3.,  4.],\n",
       "           [ 5.,  6.,  7.,  8.,  9.],\n",
       "           [10., 11., 12., 13., 14.],\n",
       "           [15., 16., 17., 18., 19.],\n",
       "           [20., 21., 22., 23., 24.]]]]),\n",
       " tensor([[[[-1., -1., -1., -1., -1., -1., -1.],\n",
       "           [-1.,  0.,  1.,  2.,  3.,  4., -1.],\n",
       "           [-1.,  5.,  6.,  7.,  8.,  9., -1.],\n",
       "           [-1., 10., 11., 12., 13., 14., -1.],\n",
       "           [-1., 15., 16., 17., 18., 19., -1.],\n",
       "           [-1., 20., 21., 22., 23., 24., -1.],\n",
       "           [-1., -1., -1., -1., -1., -1., -1.]]]]))"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.arange(25, dtype=torch.float).view(1, 1, 5, 5)\n",
    "pad = nn.ConstantPad2d([1, 1, 1, 1], value=-1)\n",
    "outputs = pad(inputs)\n",
    "inputs, outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[[[ 0.,  1.,  2.,  3.,  4.],\n",
       "           [ 5.,  6.,  7.,  8.,  9.],\n",
       "           [10., 11., 12., 13., 14.],\n",
       "           [15., 16., 17., 18., 19.],\n",
       "           [20., 21., 22., 23., 24.]]]]),\n",
       " tensor([[[[ 0.,  0.,  1.,  2.,  3.,  4.,  4.],\n",
       "           [ 0.,  0.,  1.,  2.,  3.,  4.,  4.],\n",
       "           [ 5.,  5.,  6.,  7.,  8.,  9.,  9.],\n",
       "           [10., 10., 11., 12., 13., 14., 14.],\n",
       "           [15., 15., 16., 17., 18., 19., 19.],\n",
       "           [20., 20., 21., 22., 23., 24., 24.],\n",
       "           [20., 20., 21., 22., 23., 24., 24.]]]]))"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.arange(25, dtype=torch.float).view(1, 1, 5, 5)\n",
    "pad = nn.ReplicationPad2d([1, 1, 1, 1])\n",
    "outputs = pad(inputs)\n",
    "inputs, outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[[[ 0.,  1.,  2.,  3.,  4.],\n",
       "           [ 5.,  6.,  7.,  8.,  9.],\n",
       "           [10., 11., 12., 13., 14.],\n",
       "           [15., 16., 17., 18., 19.],\n",
       "           [20., 21., 22., 23., 24.]]]]),\n",
       " tensor([[[[ 6.,  5.,  6.,  7.,  8.,  9.,  8.],\n",
       "           [ 1.,  0.,  1.,  2.,  3.,  4.,  3.],\n",
       "           [ 6.,  5.,  6.,  7.,  8.,  9.,  8.],\n",
       "           [11., 10., 11., 12., 13., 14., 13.],\n",
       "           [16., 15., 16., 17., 18., 19., 18.],\n",
       "           [21., 20., 21., 22., 23., 24., 23.],\n",
       "           [16., 15., 16., 17., 18., 19., 18.]]]]))"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inputs = torch.arange(25, dtype=torch.float).view(1, 1, 5, 5)\n",
    "pad = nn.ReflectionPad2d([1, 1, 1, 1])\n",
    "outputs = pad(inputs)\n",
    "inputs, outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "常数补全 = tensor([[[[-1., -1., -1., -1., -1., -1.],\n",
      "          [-1.,  0.,  1.,  2.,  3., -1.],\n",
      "          [-1.,  4.,  5.,  6.,  7., -1.],\n",
      "          [-1.,  8.,  9., 10., 11., -1.],\n",
      "          [-1., -1., -1., -1., -1., -1.]]]])\n",
      "重复补全 = tensor([[[[ 0.,  0.,  1.,  2.,  3.,  3.],\n",
      "          [ 0.,  0.,  1.,  2.,  3.,  3.],\n",
      "          [ 4.,  4.,  5.,  6.,  7.,  7.],\n",
      "          [ 8.,  8.,  9., 10., 11., 11.],\n",
      "          [ 8.,  8.,  9., 10., 11., 11.]]]])\n",
      "反射补全 = tensor([[[[ 5.,  4.,  5.,  6.,  7.,  6.],\n",
      "          [ 1.,  0.,  1.,  2.,  3.,  2.],\n",
      "          [ 5.,  4.,  5.,  6.,  7.,  6.],\n",
      "          [ 9.,  8.,  9., 10., 11., 10.],\n",
      "          [ 5.,  4.,  5.,  6.,  7.,  6.]]]])\n"
     ]
    }
   ],
   "source": [
    "inputs = torch.arange(12, dtype=torch.float).view(1, 1, 3, 4)\n",
    "pad = nn.ConstantPad2d(padding=[1, 1, 1, 1], value=-1)\n",
    "print ('常数补全 = {}'.format(pad(inputs)))\n",
    "pad = nn.ReplicationPad2d(padding=[1, 1, 1, 1])\n",
    "print ('重复补全 = {}'.format(pad(inputs)))\n",
    "pad = nn.ReflectionPad2d(padding=[1, 1, 1, 1])\n",
    "print ('反射补全 = {}'.format(pad(inputs)))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
